package com.magiccompass.alipay.barcode.util;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.magiccompass.alipay.barcode.common.DicInit;
import com.magiccompass.alipay.barcode.constants.BusinessLogicConstants;
import com.magiccompass.alipay.barcode.entity.MerchantInfo;
import com.magiccompass.alipay.barcode.entity.MerchantTransaction;
import com.magiccompass.alipay.barcode.entity.MerchantTransactionDetail;
import com.magiccompass.alipay.barcode.entity.ViewMerchantTransactionStatusRecords;
import com.magiccompass.alipay.barcode.model.MerchantTransactionSingleQueryModel;
import com.magiccompass.alipay.barcode.pageform.MerchantInputProductPageForm;
import com.magiccompass.alipay.barcode.pageform.MerchantInputProductPageFormDetail;
import com.magiccompass.alipay.barcode.pageform.MerchantTransactionListPageForm;
import com.magiccompass.alipay.barcode.service.MerchantBusinessService;
import com.magiccompass.alipay.barcode.service.MerchantProductInputService;

public class MerchantTransactionUtil {
	public static MerchantTransaction makeMerchantTransaction(MerchantInputProductPageForm mipp, MerchantProductInputService mpiService, MerchantBusinessService mbService){
		MerchantTransaction mt = new MerchantTransaction();
		mt.setMerchant(mbService.findMerchantById(1));
		mt.setOrderDetails(makeMerchantTransactionDetail(mipp,mt,mpiService));
		mt.setTotalAmount(getTotalAmount(mipp));
		mt.setCreateBy(BusinessLogicConstants.SYSTEM_CREATOR_ID);
		mt.setType("B");
		return mt;
	}
	
	public static MerchantTransaction makeBasicMerchantTransaction(MerchantInfo m, BigDecimal totalAmt, MerchantBusinessService mbService){
		MerchantTransaction mt = new MerchantTransaction();
		mt.setMerchant(m);
		mt.setTotalAmount(totalAmt);
		mt.setCreateBy(BusinessLogicConstants.SYSTEM_CREATOR_ID);
		mbService.save(mt);
		return mt;
	}
	
	private static Set<MerchantTransactionDetail> makeMerchantTransactionDetail(MerchantInputProductPageForm mipp,MerchantTransaction mt, MerchantProductInputService mpiService){
		Set<MerchantTransactionDetail> returnSet = new HashSet<MerchantTransactionDetail>();
		MerchantTransactionDetail aRowDetail;
		BigDecimal aSinglePrice;
		Integer aSingleQuantity;
		BigDecimal aRowTotalAmt;
		for(MerchantInputProductPageFormDetail aPageInputProductDetail:mipp.getProductList4Page()){
			aRowDetail = new MerchantTransactionDetail();
			aSinglePrice = aPageInputProductDetail.getProductPrice();
			aSingleQuantity = aPageInputProductDetail.getQuantity();
			aRowTotalAmt = aSinglePrice.multiply(new BigDecimal(aSingleQuantity));
			aRowDetail.setAmount(aRowTotalAmt);
			aRowDetail.setCreateBy(BusinessLogicConstants.SYSTEM_CREATOR_ID);
			aRowDetail.setDelFlag("F");
			aRowDetail.setProduct(mpiService.findProductById(aPageInputProductDetail.getProductId()));
			aRowDetail.setQuantity(aPageInputProductDetail.getQuantity());
			aRowDetail.setMerchantTransaction(mt);
			returnSet.add(aRowDetail);
		}
		return returnSet;
	}
	
	private static BigDecimal getTotalAmount(MerchantInputProductPageForm mipp){
		BigDecimal totalAmt = new BigDecimal(0);
		BigDecimal aSinglePrice;
		Integer aSingleQuantity;
		BigDecimal aRowTotalAmt;
		for(MerchantInputProductPageFormDetail aPageInputProductDetail:mipp.getProductList4Page()){
			aSinglePrice = aPageInputProductDetail.getProductPrice();
			aSingleQuantity = aPageInputProductDetail.getQuantity();
			aRowTotalAmt = aSinglePrice.multiply(new BigDecimal(aSingleQuantity));
			totalAmt = totalAmt.add(aRowTotalAmt);
		}
		return totalAmt;
	}
	
	public static boolean isMerchantTransactionCanBeCancelled(MerchantTransaction mt){
		//TODO need know when will "daily shift" happen, and it's frequency.
		Timestamp mtCreateTime = mt.getCreateTime();
		
		Calendar calendarMTCreateDateEnd = Calendar.getInstance();
		calendarMTCreateDateEnd.setTimeInMillis(mtCreateTime.getTime());
		calendarMTCreateDateEnd.set(Calendar.HOUR_OF_DAY, 23);
		calendarMTCreateDateEnd.set(Calendar.MINUTE, 59);
		calendarMTCreateDateEnd.set(Calendar.SECOND, 59);
		calendarMTCreateDateEnd.set(Calendar.MILLISECOND, 999);
		
		Calendar calendarNow = Calendar.getInstance();
		
		if(calendarNow.before(calendarMTCreateDateEnd) && "S".equals(mt.getStatus())){
			return true;
		}else{
			return false;
		}
	}
	
	public static boolean isMerchantTransactionCanBeReversed(MerchantTransaction mt){
		//TODO need know when will "daily shift" happen, and it's frequency.
		Timestamp mtCreateTime = mt.getCreateTime();
		
		Calendar calendarMTCreateDateEnd = Calendar.getInstance();
		calendarMTCreateDateEnd.setTimeInMillis(mtCreateTime.getTime());
		calendarMTCreateDateEnd.set(Calendar.HOUR_OF_DAY, 23);
		calendarMTCreateDateEnd.set(Calendar.MINUTE, 59);
		calendarMTCreateDateEnd.set(Calendar.SECOND, 59);
		calendarMTCreateDateEnd.set(Calendar.MILLISECOND, 999);
		
		Calendar calendarNow = Calendar.getInstance();
		
		if(calendarNow.before(calendarMTCreateDateEnd) && "U".equals(mt.getStatus())){
			return true;
		}else{
			return false;
		}
	}
	
	public static boolean isMerchantTransactionCanBeRefund(MerchantTransaction mt){
		//TODO need know when will "daily shift" happen, and it's frequency.
		Timestamp mtCreateTime = mt.getCreateTime();
		
		Calendar calendarMThasBeenDailyShifted = Calendar.getInstance();
		calendarMThasBeenDailyShifted.setTimeInMillis(mtCreateTime.getTime());
		calendarMThasBeenDailyShifted.add(Calendar.DATE, 1);
		calendarMThasBeenDailyShifted.set(Calendar.HOUR_OF_DAY, 2);
		calendarMThasBeenDailyShifted.set(Calendar.MINUTE, 0);
		calendarMThasBeenDailyShifted.set(Calendar.SECOND, 0);
		calendarMThasBeenDailyShifted.set(Calendar.MILLISECOND, 0);
		
		Calendar calendarNow = Calendar.getInstance();
		
		if(calendarNow.after(calendarMThasBeenDailyShifted) && "S".equals(mt.getStatus())){
			return true;
		}else{
			return false;
		}
	}
	
	public static List<MerchantTransactionListPageForm> makeMerchantTransactionListPageForm(List<MerchantTransaction> mtList){
		List<MerchantTransactionListPageForm> returnList = null;
		if(mtList != null && mtList.size()>0){
			returnList = new ArrayList<MerchantTransactionListPageForm>();
			MerchantTransactionListPageForm mtlpf = null;
			for(MerchantTransaction mt:mtList){
				mtlpf = new MerchantTransactionListPageForm();
				mtlpf.setId(mt.getId());
				mtlpf.setMerchantName(mt.getMerchant().getMerchantName());
				mtlpf.setTotalAmount(mt.getTotalAmount());
				mtlpf.setStatus(DicInit.getSystemCode("merchant_transaction", "status", mt.getStatus()));
				mtlpf.setStatusCode(mt.getStatus());
				mtlpf.setCanBeCancelled(isMerchantTransactionCanBeCancelled(mt));
				mtlpf.setCanBeReversed(isMerchantTransactionCanBeReversed(mt));
				mtlpf.setCanBeRefund(isMerchantTransactionCanBeRefund(mt));
				mtlpf.setCreateTimeStr(DateTimeUtil.formatTimeByFormat(mt.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
				mtlpf.setUpdateTimeStr(DateTimeUtil.formatTimeByFormat(mt.getUpdateTime(), "yyyy-MM-dd HH:mm:ss"));
				mtlpf.setType(DicInit.getSystemCode("merchant_transaction", "type", mt.getType()));
				mtlpf.setTypeCode(mt.getType());
				returnList.add(mtlpf);
			}
		}
		return returnList;		
	}
	
	public static MerchantTransactionSingleQueryModel makeMerchantTransactionSingleQueryModel(ViewMerchantTransactionStatusRecords mtStatusView){
		MerchantTransactionSingleQueryModel mtsqm = new MerchantTransactionSingleQueryModel();
		mtsqm.setAlipayBuyerLoginId(mtStatusView.getAlipayBuyerLoginId());
		mtsqm.setAlipayRefundTime(DateTimeUtil.formatTimeByFormat(mtStatusView.getAlipayRefundTime(), "yyyy-MM-dd HH:mm:ss"));
		mtsqm.setAlipayReverseTime(DateTimeUtil.formatTimeByFormat(mtStatusView.getAlipayReverseTime(), "yyyy-MM-dd HH:mm:ss"));
		mtsqm.setCancelBy(mtStatusView.getCancelBy());
		mtsqm.setCancelRequestTime(DateTimeUtil.formatTimeByFormat(mtStatusView.getCancelRequestTime(), "yyyy-MM-dd HH:mm:ss"));
		mtsqm.setMakePaymentBy(mtStatusView.getMakePaymentBy());
		mtsqm.setPaymentStatus(mtStatusView.getPaymentStatus());
		mtsqm.setRefundBy(mtStatusView.getRefundBy());
		mtsqm.setRefundRequestTime(DateTimeUtil.formatTimeByFormat(mtStatusView.getRefundRequestTime(), "yyyy-MM-dd HH:mm:ss"));
		mtsqm.setReverseBy(mtStatusView.getReverseBy());
		mtsqm.setReverseRequestTime(DateTimeUtil.formatTimeByFormat(mtStatusView.getReverseRequestTime(), "yyyy-MM-dd HH:mm:ss"));
		mtsqm.setTransactionCreateTime(DateTimeUtil.formatTimeByFormat(mtStatusView.getTransactionCreateTime(), "yyyy-MM-dd HH:mm:ss"));
		mtsqm.setTransactionId(mtStatusView.getTransactionId());
		mtsqm.setTransactionStatus(DicInit.getSystemCode("merchant_transaction", "status", mtStatusView.getTransactionStatus()));
		mtsqm.setTransactionUpdateTime(DateTimeUtil.formatTimeByFormat(mtStatusView.getTransactionUpdateTime(), "yyyy-MM-dd HH:mm:ss"));
		
		mtsqm.setPaymentRequestTime(DateTimeUtil.formatTimeByFormat(mtStatusView.getPaymentRequestTime(), "yyyy-MM-dd HH:mm:ss"));
		mtsqm.setTransactionType(DicInit.getSystemCode("merchant_transaction", "type", mtStatusView.getTransactionType()));
		mtsqm.setAlipayPayTime(DateTimeUtil.formatTimeByFormat(mtStatusView.getAlipayPayTime(), "yyyy-MM-dd HH:mm:ss"));
		mtsqm.setAlipayCancelTime(DateTimeUtil.formatTimeByFormat(mtStatusView.getAlipayCancelTime(), "yyyy-MM-dd HH:mm:ss"));
		return mtsqm;		
	}
}